home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Comm / AmiTCP30b2.lha / src / netlib / _open.c < prev    next >
C/C++ Source or Header  |  1994-04-04  |  3KB  |  156 lines

  1. RCS_ID_C="$Id: _open.c,v 3.3 1994/04/04 01:27:59 jraja Exp $";
  2. /*
  3.  * _open.c - Unix compatible open()
  4.  *
  5.  * Author: jraja <Jarno.Rajahalme@hut.fi>
  6.  *
  7.  * This file is part of the AmiTCP/IP Network Support Library.
  8.  *
  9.  * Copyright © 1993 AmiTCP/IP Group, <amitcp-group@hut.fi>
  10.  *                  Helsinki University of Technology, Finland.
  11.  *                  All rights reserved.
  12.  *
  13.  * Created      : Tue Mar  8 01:07:48 1994 jraja
  14.  * Last modified: Wed Mar 30 10:22:04 1994 jraja
  15.  *
  16.  */
  17.  
  18. #include <ios1.h>
  19. #include <fcntl.h>
  20. #include <stdlib.h>
  21. #include <dos.h>
  22. #include <string.h>
  23. #include <errno.h>
  24. #include <dos/dos.h>
  25. #include <proto/dos.h>
  26. #include <proto/usergroup.h>
  27. #include <stdarg.h>
  28. #include <unistd.h>
  29.  
  30. #include <bsdsocket.h>
  31.  
  32. #include "netlib.h"
  33.  
  34. extern int (*__closefunc)(int);
  35.  
  36. __stdargs int
  37. __open(const char *name, int mode, ...)
  38. {
  39.   struct UFB *ufb;
  40.   int         fd;
  41.   int         flags;
  42.   char        newfile = TRUE;
  43.   BPTR        file;
  44.  
  45.   /*
  46.    * Set up __closefunc (which is used at cleanup)
  47.    */
  48.   __closefunc = __close;
  49.  
  50.   /*
  51.    * Check for the break signals
  52.    */
  53.   __chkabort();
  54.  
  55.   /*
  56.    * find first free ufb
  57.    */
  58.   ufb = __allocufb(&fd);
  59.   if (ufb == NULL)
  60.     return -1; /* errno is set by the __allocufb() */
  61.  
  62.   /*
  63.    * malloc space for the name & copy it
  64.    */
  65.   if ((ufb->ufbfn = malloc(strlen(name)+1)) == NULL) {
  66.     SET_OSERR(ERROR_NO_FREE_STORE);
  67.     errno = ENOMEM;
  68.     return -1;
  69.   }
  70.   strcpy(ufb->ufbfn, name);
  71.   /*
  72.    * Translate mode to ufb flags
  73.    */
  74.   switch (mode & (O_WRONLY | O_RDWR)) {
  75.   case O_RDONLY:
  76.     if (mode & (O_APPEND | O_CREAT | O_TRUNC | O_EXCL)) {
  77.       errno = EINVAL;
  78.       return -1;
  79.     }
  80.     flags = UFB_RA;
  81.     break;
  82.   case O_WRONLY:
  83.     flags = UFB_WA;
  84.     break;
  85.   case O_RDWR:
  86.     flags = UFB_RA | UFB_WA;
  87.     break;
  88.   default:
  89.     errno = EINVAL;
  90.     return -1;
  91.   }
  92.   if (mode & O_APPEND)
  93.     flags |= UFB_APP;
  94.   if (mode & O_XLATE)
  95.     flags |= UFB_XLAT;
  96.   if (mode & O_TEMP)
  97.     flags |= UFB_TEMP;
  98.   if (mode & O_CREAT) {
  99.     BPTR lock;
  100.     if (lock = Lock((char *)name, SHARED_LOCK)) {
  101.       if (mode & O_EXCL) {
  102.     UnLock(lock);
  103.     errno = EEXIST;
  104.     free(ufb->ufbfn);
  105.     return -1;
  106.       }
  107.  
  108.       if (mode & O_TRUNC)
  109.     newfile = FALSE;
  110.       else
  111.     mode &= ~O_CREAT;
  112.  
  113.       UnLock(lock);
  114.     }
  115.   }
  116.   if (mode & O_CREAT) {
  117.     if ((file = Open((char *)name, MODE_NEWFILE)) == NULL)
  118.       goto osfail;
  119.  
  120.     if (newfile) {
  121.       va_list va;
  122.       int cmode;
  123.  
  124.       va_start(va, mode);
  125.  
  126.       cmode = va_arg(va, int) & ~getumask();
  127.       
  128.       chmod((char *)name, cmode); /* hope this doesn't fail :-) */
  129.     }
  130.   }
  131.   else {
  132.     if ((file = Open((char *)name,
  133.              (flags & UFB_WA && mode & O_LOCK) ? 
  134.              MODE_READWRITE : MODE_OLDFILE)) == NULL)
  135.       goto osfail;
  136.   }
  137.  
  138.   /*
  139.    * All done! Setting the ufb->ufbflg field to non-zero value marks
  140.    * this ufb used. 
  141.    */
  142.   ufb->ufbflg = flags;
  143.   ufb->ufbfh = (long)file;
  144.  
  145.   return fd;
  146.  
  147. osfail:
  148.   {
  149.     int code = IoErr();
  150.     if (ufb->ufbfn)
  151.       free(ufb->ufbfn);
  152.     set_errno(code);
  153.   }
  154.   return -1;
  155. }
  156.